Tanulja meg, hogyan implementálhat React Error Boundary-kat hookokkal az erĹ‘forrás-betöltĂ©si hibák elegáns kezelĂ©sĂ©re, javĂtva a felhasználĂłi Ă©lmĂ©nyt Ă©s az alkalmazás stabilitását.
Robusztus erőforrás-betöltés Reactben: Az Error Boundary-k mesteri használata Hookokkal
A modern webalkalmazásokban az erĹ‘források aszinkron betöltĂ©se bevett gyakorlat. Legyen szĂł API-bĂłl törtĂ©nĹ‘ adatlekĂ©rĂ©srĹ‘l, kĂ©pek betöltĂ©sĂ©rĹ‘l vagy modulok importálásárĂłl, a betöltĂ©s során fellĂ©pĹ‘ potenciális hibák kezelĂ©se kulcsfontosságĂş a zökkenĹ‘mentes felhasználĂłi Ă©lmĂ©ny szempontjábĂłl. A React Error Boundary-k mechanizmust biztosĂtanak a JavaScript-hibák elkapására a gyermekkomponens-fájuk bármely pontján, ezen hibák naplĂłzására, Ă©s egy tartalĂ©k felhasználĂłi felĂĽlet (fallback UI) megjelenĂtĂ©sĂ©re az egĂ©sz alkalmazás összeomlása helyett. Ez a cikk azt vizsgálja, hogyan használhatjuk hatĂ©konyan az Error Boundary-kat a React Hookokkal egyĂĽtt az erĹ‘forrás-betöltĂ©si hibák kezelĂ©sĂ©re.
Az Error Boundary-k megértése
A React 16 előtt a komponensek renderelése során kezeletlen JavaScript-hibák megrongálták a React belső állapotát, és rejtélyes hibákat okoztak a későbbi renderelések során. Az Error Boundary-k ezt úgy oldják meg, hogy egyfajta mindent elkapó blokként működnek a gyermekkomponenseikben előforduló hibák számára. Ezek olyan React komponensek, amelyek az alábbi életciklus-metódusok egyikét vagy mindkettőt implementálják:
static getDerivedStateFromError(error): Ez a statikus metĂłdus akkor hĂvĂłdik meg, miután egy leszármazott komponens hibát dobott. ArgumentumkĂ©nt megkapja a dobott hibát, Ă©s egy Ă©rtĂ©kkel tĂ©r vissza a komponens állapotának frissĂtĂ©sĂ©hez.componentDidCatch(error, info): Ez az Ă©letciklus-metĂłdus akkor hĂvĂłdik meg, miután egy leszármazott komponens hibát dobott. ArgumentumkĂ©nt megkapja a dobott hibát, valamint egy objektumot, amely informáciĂłt tartalmaz arrĂłl, hogy melyik komponens dobta a hibát. Használhatja a hibainformáciĂłk naplĂłzására.
Fontos, hogy az Error Boundary-k csak a renderelési fázisban, az életciklus-metódusokban és a teljes alattuk lévő fa konstruktoraiban keletkező hibákat kapják el. Nem kapják el a hibákat a következők esetében:
- Eseménykezelők (tudjon meg többet az alábbi szakaszban)
- Aszinkron kĂłd (pl.
setTimeoutvagyrequestAnimationFramevisszahĂvások) - Szerveroldali renderelĂ©s
- Magában az Error Boundary komponensben dobott hibák (a gyermekei helyett)
Error Boundary-k és React Hookok: Egy erőteljes kombináció
MĂg hagyományosan osztálykomponenseket használtak az Error Boundary-k implementálására, a React Hookok egy tömörebb Ă©s funkcionálisabb megközelĂtĂ©st kĂnálnak. LĂ©trehozhatunk egy ĂşjrafelhasználhatĂł useErrorBoundary hookot, amely magába foglalja a hibakezelĂ©si logikát, Ă©s kĂ©nyelmes mĂłdot biztosĂt azon komponensek becsomagolására, amelyek hibát dobhatnak az erĹ‘forrás-betöltĂ©s során.
Egyéni useErrorBoundary Hook létrehozása
Itt egy példa egy useErrorBoundary hookra:
import { useState, useCallback } from 'react';
function useErrorBoundary() {
const [error, setError] = useState(null);
const resetError = useCallback(() => {
setError(null);
}, []);
const captureError = useCallback((e) => {
setError(e);
}, []);
const ErrorBoundary = useCallback(({ children, fallback }) => {
if (error) {
return fallback ? fallback : An error occurred: {error.message || String(error)};
}
return children;
}, [error]);
return { ErrorBoundary, captureError, error, resetError };
}
export default useErrorBoundary;
Magyarázat:
useState: AuseState-et használjuk a hibaállapot kezelĂ©sĂ©re. Kezdetben a hibátnull-ra állĂtja.useCallback: AuseCallback-et aresetErrorĂ©scaptureErrorfĂĽggvĂ©nyek memoizálására használjuk. Ez jĂł gyakorlat a felesleges ĂşjrarenderelĂ©sek elkerĂĽlĂ©sĂ©re, ha ezeket a fĂĽggvĂ©nyeket propkĂ©nt adjuk tovább.ErrorBoundaryKomponens: Ez egyuseCallback-kel lĂ©trehozott funkcionális komponens, amelychildrenĂ©s egy opcionálisfallbackpropot kap. Ha hiba van az állapotban, akkor vagy a megadottfallbackkomponenst, vagy egy alapĂ©rtelmezett hibaĂĽzenetet renderel. EgyĂ©bkĂ©nt a gyermekeket rendereli. Ez működik Error Boundary-kĂ©nt. A `[error]` fĂĽggĹ‘sĂ©gi tömb biztosĂtja, hogy ĂşjrarenderelĹ‘djön, amikor a `error` állapot megváltozik.captureErrorFĂĽggvĂ©ny: Ezt a fĂĽggvĂ©nyt a hibaállapot beállĂtására használjuk. Ezt egytry...catchblokkon belĂĽl fogja meghĂvni az erĹ‘források betöltĂ©sekor.resetErrorFĂĽggvĂ©ny: Ez a fĂĽggvĂ©ny törli a hibaállapotot, lehetĹ‘vĂ© tĂ©ve a komponens számára, hogy Ăşjrarenderelje a gyermekeit (potenciálisan Ăşjra megkĂsĂ©relve az erĹ‘forrás betöltĂ©sĂ©t).
Erőforrás-betöltés implementálása hibakezeléssel
Most nézzük meg, hogyan használhatjuk ezt a hookot az erőforrás-betöltési hibák kezelésére. Vegyünk egy komponenst, amely felhasználói adatokat kér le egy API-ból:
import React, { useState, useEffect } from 'react';
import useErrorBoundary from './useErrorBoundary';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const { ErrorBoundary, captureError, error, resetError } = useErrorBoundary();
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (e) {
captureError(e);
}
};
fetchData();
}, [userId, captureError]);
if (error) {
return (
Failed to load user data. {user.name}
Email: {user.email}
{/* Other user details */}Magyarázat:
- Importáljuk a
useErrorBoundaryhookot. - MeghĂvjuk a hookot, hogy megkapjuk az
ErrorBoundarykomponenst, acaptureErrorfüggvényt, azerrorállapotot és aresetErrorfüggvényt. - Az
useEffecthookon belĂĽl az API-hĂvást egytry...catchblokkba csomagoljuk. - Ha hiba törtĂ©nik az API-hĂvás során, meghĂvjuk a
captureError(e)-t a hibaállapot beállĂtásához. - Ha az
errorállapot be van állĂtva, akkor azErrorBoundarykomponenst rendereljĂĽk. EgyĂ©nifallbackpropot adunk meg, amely egy hibaĂĽzenetet Ă©s egy "Ăšjra" gombot jelenĂt meg. A gombra kattintva aresetErrorhĂvĂłdik meg, ami törli a hibaállapotot, ĂşjrarenderelĂ©st váltva ki Ă©s Ăşjra megkĂsĂ©relve az adatlekĂ©rĂ©st. - Ha nem törtĂ©nt hiba, Ă©s a felhasználĂłi adatok betöltĹ‘dtek, akkor a felhasználĂłi profil rĂ©szleteit rendereljĂĽk.
KĂĽlönbözĹ‘ tĂpusĂş erĹ‘forrás-betöltĂ©si hibák kezelĂ©se
A kĂĽlönbözĹ‘ tĂpusĂş erĹ‘forrás-betöltĂ©si hibák eltĂ©rĹ‘ kezelĂ©si stratĂ©giákat igĂ©nyelhetnek. ĂŤme nĂ©hány gyakori forgatĂłkönyv Ă©s azok kezelĂ©se:
Hálózati hibák
HálĂłzati hibák akkor fordulnak elĹ‘, amikor a kliens nem tud csatlakozni a szerverhez (pl. hálĂłzati kimaradás vagy szerver leállás miatt). A fenti pĂ©lda már kezeli az alapvetĹ‘ hálĂłzati hibákat a `response.ok` segĂtsĂ©gĂ©vel. Lehet, hogy kifinomultabb hibadetektálást szeretne hozzáadni, pĂ©ldául:
//Inside the fetchData function
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
// Consider adding specific error code handling
if (response.status === 404) {
throw new Error("User not found");
} else if (response.status >= 500) {
throw new Error("Server error. Please try again later.");
} else {
throw new Error(`HTTP error! status: ${response.status}`);
}
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error.message === 'Failed to fetch') {
// Likely a network error
captureError(new Error('Network error. Please check your internet connection.'));
} else {
captureError(error);
}
}
Ebben az esetben ĂĽzenetet jelenĂthet meg a felhasználĂłnak, jelezve, hogy hálĂłzati csatlakozási problĂ©ma van, Ă©s javasolhatja, hogy ellenĹ‘rizze az internetkapcsolatát.
API hibák
API hibák akkor fordulnak elő, amikor a szerver hibaválaszt ad vissza (pl. 400 Bad Request vagy 500 Internal Server Error). Ahogy fentebb látható, ellenőrizheti a `response.status`-t és kezelheti ezeket a hibákat megfelelően.
Adatfeldolgozási hibák
Adatfeldolgozási hibák akkor fordulnak elĹ‘, amikor a szerver válasza nem a várt formátumban van, Ă©s nem lehet feldolgozni (pl. Ă©rvĂ©nytelen JSON). Ezeket a hibákat Ăşgy kezelheti, hogy a response.json() hĂvást egy try...catch blokkba csomagolja:
//Inside the fetchData function
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error instanceof SyntaxError) {
captureError(new Error('Failed to parse data from server.'));
} else {
captureError(error);
}
}
Képbetöltési hibák
Képek betöltéséhez használhatja az onError eseménykezelőt az <img> tagen:
function MyImage({ src, alt }) {
const { ErrorBoundary, captureError } = useErrorBoundary();
const [imageLoaded, setImageLoaded] = useState(false);
const handleImageLoad = () => {
setImageLoaded(true);
};
const handleImageError = (e) => {
captureError(new Error(`Failed to load image: ${src}`));
};
return (
Failed to load image.